<template>
  <transition name="fade">
    <div
      v-if="visible"
      class="fixed inset-0 z-50 bg-black/90 flex flex-col"
      @click="handleBackdropClick"
    >
      <!-- 图片预览区域 -->
      <div
        ref="container"
        class="flex-1 relative overflow-hidden touch-none"
        @touchstart="onTouchStart"
        @touchmove="onTouchMove"
        @touchend="onTouchEnd"
        @wheel="onWheel"
      >
        <!-- 动态渲染可见范围内的图片 -->
        <div
          v-for="index in visibleIndexes"
          :key="index"
          class="absolute top-0 h-full flex items-center justify-center transition-transform duration-300 will-change-transform"
          :class="{ 'transition-all duration-300': !isDragging }"
          :style="{
            transform: `translateX(${getImagePosition(index)}px)`,
            width: `${containerWidth}px`,
            opacity: currentIndex === index ? 1 : 0.7,
            pointerEvents: 'auto',
            zIndex: 100 - Math.abs(index - currentIndex)
          }"
        >
          <div class="flex justify-center items-center p-2 relative">
            <!-- 顶部操作栏 - 直接显示，无过渡效果 -->
            <div
              v-show="currentIndex === index"
              class="absolute top-0 right-0 flex justify-end p-15 no-close w-110"
            >
              <div
                class="c-translucent-balck50 h-32 w-32 rounded-[50%] text-16 flex items-center justify-center iconfont icon-shanchu text-white no-close"
                @click.stop="deleteImage"
              />
              <div
                class="c-translucent-balck50 h-32 w-32 rounded-[50%] text-16 flex items-center justify-center iconfont icon-xiazai text-white no-close ml-15"
                @click.stop="downloadImage"
              />
            </div>

            <img
              :src="images[index].url"
              :alt="`预览图片 ${index + 1}`"
              class="max-w-full max-h-[80vh] object-contain transition-opacity duration-300 rounded-10"
              :class="{
                'opacity-100': imageLoaded[index],
                'opacity-0': !imageLoaded[index]
              }"
              @load="() => onImageLoad(index)"
            />

            <!-- 加载指示器 -->
            <div
              v-if="!imageLoaded[index]"
              class="absolute inset-0 flex items-center justify-center"
            >
              <div
                class="w-10 h-10 border-t-2 border-blue-500 border-solid rounded-full animate-spin"
              />
            </div>

            <!-- 底部信息栏 - 直接显示，无过渡效果 -->
            <div
              v-show="currentIndex === index"
              class="absolute bottom-0 left-0 right-0 flex justify-between p-15"
            >
              <div
                class="text-white c-translucent-balck50 px-10 leading-21 h-21 rounded-10 text-12"
              >
                {{ currentIndex + 1 }} / {{ images.length }}
              </div>
              <div
                class="text-white c-translucent-balck50 px-10 leading-21 h-21 rounded-10 text-12"
              >
                {{ images[index].createTime }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from "vue";
import { showToast } from "vant";

const props = defineProps({
  visible: {
    type: Boolean,
    required: true
  },
  images: {
    type: Array,
    required: true,
    default: () => []
  },
  currentIndex: {
    type: Number,
    required: true,
    default: 0
  }
});

const emit = defineEmits(["update:visible", "update:currentIndex", "delete"]);

// 响应式数据
const container = ref(null);
const containerWidth = ref(0);
const startX = ref(0);
const isDragging = ref(false);
const dragOffset = ref(0);
const imageLoaded = ref([]);
const touchStartTime = ref(0);
const velocity = ref(0);
const lastMoveTime = ref(0);
const lastMoveX = ref(0);

// 计算可见图片索引（仅当前页和相邻两页）
const visibleIndexes = computed(() => {
  const indexes = new Set();

  // 显示当前页及相邻两页
  for (let i = -1; i <= 1; i++) {
    const index = props.currentIndex + i;
    if (index >= 0 && index < props.images.length) {
      indexes.add(index);
    }
  }

  return Array.from(indexes).sort((a, b) => a - b);
});

// 获取图片位置
const getImagePosition = index => {
  return index * containerWidth.value + dragOffset.value;
};

// 更新容器宽度
const updateContainerWidth = () => {
  if (container.value) {
    containerWidth.value = container.value.clientWidth;
  }
};

// 重置位置
const resetPosition = () => {
  dragOffset.value = -props.currentIndex * containerWidth.value;
};

// 监听当前索引变化
watch(
  () => props.currentIndex,
  newIndex => {
    // 确保索引有效
    const validIndex = Math.max(0, Math.min(newIndex, props.images.length - 1));
    if (validIndex !== newIndex) {
      emit("update:currentIndex", validIndex);
      return;
    }

    resetPosition();

    // 预加载相邻图片
    preloadImages(validIndex);
  }
);

// 预加载图片
const preloadImages = index => {
  const indexesToPreload = new Set();

  // 预加载当前及相邻图片
  for (let i = -1; i <= 1; i++) {
    const targetIndex = index + i;
    if (targetIndex >= 0 && targetIndex < props.images.length) {
      indexesToPreload.add(targetIndex);
    }
  }

  // 创建Image对象预加载
  indexesToPreload.forEach(idx => {
    if (!imageLoaded.value[idx]) {
      const img = new Image();
      img.src = props.images[idx].url;
      img.onload = () => {
        imageLoaded.value[idx] = true;
      };
    }
  });
};

// 监听可见状态
watch(
  () => props.visible,
  newVal => {
    if (newVal) {
      // 初始化图片加载状态
      imageLoaded.value = Array(props.images.length).fill(false);

      nextTick(() => {
        updateContainerWidth();
        resetPosition();
        preloadImages(props.currentIndex);
      });
      document.addEventListener("touchmove", preventScroll, { passive: false });
    } else {
      document.removeEventListener("touchmove", preventScroll);
      dragOffset.value = 0;
    }
  }
);

// 监听图片数组变化
watch(
  () => props.images,
  newImages => {
    imageLoaded.value = Array(newImages.length).fill(false);
    if (props.visible) {
      nextTick(() => {
        updateContainerWidth();
        resetPosition();
        preloadImages(props.currentIndex);
      });
    }
  }
);

// 阻止滚动
const preventScroll = e => {
  if (isDragging.value) {
    e.preventDefault();
  }
};

// 触摸开始
const onTouchStart = e => {
  startX.value = e.touches[0].clientX;
  isDragging.value = true;
  touchStartTime.value = Date.now();
  velocity.value = 0;
  lastMoveTime.value = Date.now();
  lastMoveX.value = startX.value;
};

// 触摸移动
const onTouchMove = e => {
  if (!isDragging.value || containerWidth.value <= 0) return;

  const currentX = e.touches[0].clientX;
  const diffX = currentX - startX.value;
  startX.value = currentX;

  // 计算速度 (px/ms)
  const now = Date.now();
  const timeDiff = now - lastMoveTime.value;
  const moveDiff = currentX - lastMoveX.value;

  if (timeDiff > 0) {
    velocity.value = moveDiff / timeDiff;
  }

  lastMoveTime.value = now;
  lastMoveX.value = currentX;

  // 更新偏移量
  dragOffset.value += diffX;

  // 边界检查：防止滑动过头
  const maxOffset = containerWidth.value * 0.3; // 允许稍微超出
  const minOffset =
    -(props.images.length - 1) * containerWidth.value -
    containerWidth.value * 0.3;
  dragOffset.value = Math.min(maxOffset, Math.max(minOffset, dragOffset.value));
};

// 触摸结束
const onTouchEnd = () => {
  if (!isDragging.value || containerWidth.value <= 0) return;
  isDragging.value = false;

  // 计算当前应该显示的索引
  const currentOffset = -dragOffset.value;

  // 根据速度调整滑动距离
  const momentum = velocity.value * 100; // 乘以系数增强动量效果
  const adjustedOffset = currentOffset - momentum;

  let newIndex = Math.round(adjustedOffset / containerWidth.value);

  // 确保索引在有效范围内
  newIndex = Math.max(0, Math.min(newIndex, props.images.length - 1));

  // 更新索引
  if (newIndex !== props.currentIndex) {
    emit("update:currentIndex", newIndex);
  } else {
    // 回弹到正确位置
    resetPosition();
  }
};
// 添加滚轮事件处理函数
const onWheel = e => {
  e.preventDefault();

  // 根据滚轮方向切换图片
  if (e.deltaY > 0) {
    // 向下滚动 - 下一张
    const newIndex = Math.min(props.currentIndex + 1, props.images.length - 1);
    if (newIndex !== props.currentIndex) {
      emit("update:currentIndex", newIndex);
    }
  } else {
    // 向上滚动 - 上一张
    const newIndex = Math.max(0, props.currentIndex - 1);
    if (newIndex !== props.currentIndex) {
      emit("update:currentIndex", newIndex);
    }
  }
};

// 关闭预览
const closePreview = () => {
  emit("update:visible", false);
};

// 删除当前图片
const deleteImage = () => {
  if (props.images.length <= 1) {
    showToast("至少保留一张图片");
    return;
  }

  emit("delete", props.currentIndex);

  // 调整索引
  const newIndex =
    props.currentIndex >= props.images.length - 1
      ? props.images.length - 2
      : props.currentIndex;

  emit("update:currentIndex", newIndex);
  showToast("图片已删除");
};

// 下载当前图片
const downloadImage = () => {
  const currentImage = props.images[props.currentIndex].url;
  if (!currentImage) return;

  const link = document.createElement("a");
  link.href = currentImage;
  link.download = `image-${Date.now()}.${getFileExtension(currentImage)}`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);

  showToast("图片已开始下载");
};

// 获取文件扩展名
const getFileExtension = url => {
  return url.split(".").pop().split("?")[0] || "jpg";
};

// 图片加载完成
const onImageLoad = index => {
  imageLoaded.value[index] = true;
};

// 监听窗口大小变化
const handleResize = () => {
  updateContainerWidth();
  resetPosition();
};

// 处理蒙层点击事件（优化版）
const handleBackdropClick = e => {
  // 检查点击是否在操作按钮区域内
  const isButtonClick = e.target.closest(".no-close");

  // 如果点击的不是操作按钮区域，则关闭预览
  if (!isButtonClick) {
    closePreview();
  }
};

// 生命周期钩子
onMounted(() => {
  window.addEventListener("resize", handleResize);
  if (props.visible) {
    nextTick(() => {
      updateContainerWidth();
      resetPosition();
    });
  }
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  document.removeEventListener("touchmove", preventScroll);
});
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* 优化图片过渡效果 */
img {
  transition: opacity 0.3s ease;
}

/* 平滑滚动 */
.transition-all {
  transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
}
</style>
